<template>
  <div>
    <CategorySelector style="margin-bottom: 10px;"/>
    <el-card>
      <div v-if="isShowAttrList">
        <el-button type="primary" :disabled="!categoryStore.category3Id" :icon="Plus" @click="toSaveAttrValue">添加属性</el-button>
        <el-table border v-loading="loading" :data="attrList" style="margin-top:10px">
          <el-table-column type="index" align="center" label="序号" width="80px" />
          <el-table-column label="属性名称" prop="attrName" width="200px" />
          <el-table-column label="属性值列表">
            <template v-slot="{row}">
              <el-tag class="ml-2" style="margin-right:6px" type="success" v-for="attrValue in row.attrValueList" :key="attrValue.id">{{attrValue.valueName}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="200px">
            <template v-slot="{row,$index}">
              <el-button title="修改" size="small" type="warning" :icon="Edit" @click="editAttr(row,$index)"></el-button>
              <el-popconfirm title="确定要删除此条属性吗?" @confirm="deleteAttrInfo(row.id)">
                <template #reference>
                  <el-button title="删除" :icon="Delete" type="danger" size="small"></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
          </el-table>
      </div>
      <div v-else>
        <el-form>
          <el-form-item label="属性名" style="width:300px">
            <el-input  placeholder="请输入属性名" width='200px' v-model="attrInfo.attrName" />
          </el-form-item>
        </el-form>
            <el-button type="primary"  @click="addAttrValue" :disabled="!attrInfo.attrName">添加属性值</el-button>
              <el-table border :data="attrInfo.attrValueList">
                <el-table-column  label="序号" width="80" align="center" />
                <el-table-column  label="属性值名称" align="center">
                  <template v-slot="{row,$index}">
                    <el-input size="small" v-model="row.valueName" ref="inputRef" @blur="deleteCurrentRow(row,$index)" v-if="row.isShowInput" ></el-input>
                    <span v-else @dblclick="editAttrValue(row,$index)" style="display:inline-block;width:80%">{{row.valueName}}</span>
                  </template>
                </el-table-column>
                <el-table-column  label="操作" align="center">
                  <template v-slot="{row,$index}">
                    <el-popconfirm title="确定要删除此条属性值吗?" @confirm="deleteAttrValue($index)">
                      <template #reference>
                        <el-button :icon="Delete" type="danger" size="small"></el-button>
                      </template>
                    </el-popconfirm>
                  </template>
                </el-table-column>
              </el-table>
              <el-button type="primary" @click="toAddOrUpdateAttr">保存</el-button>
              <el-button type="default" @click="isShowAttrList=true">取消</el-button>
          </div>
        </el-card>
  </div>
</template>

<script lang="ts">
  import CategorySelector from '@/components/CategorySelector/index.vue'
  export default {
      name:'AttrPage',
      components:{CategorySelector}
  }
</script>

<script lang="ts" setup>
import {ref,watch,reactive,nextTick} from 'vue'
import {Plus,InfoFilled,Delete,Edit, Loading} from '@element-plus/icons-vue'
import {ElMessage} from 'element-plus'
import {useCategoryListStore} from '@/stores/categoryList'
import {reqGetAttrListDataByCategory3Id,reqAddOrUpdateAttrInfo,reqDeleteOneAttr} from '@/api/product/attr'
import type {AttrInfoModel,AttrListModel,AttrValueModel} from '@/api/product/model/attrModel'

const isShowAttrList = ref<boolean>(true)
const loading = ref(false)
// 定义一个数组存储属性列表数据
const attrList = ref<AttrListModel>([])

// 定义属性对象，收集要添加的属性信息
const attrInfo = reactive<AttrInfoModel>({
  attrName:'',
  attrValueList:[],
  categoryId:-1,
  categoryLevel:3
})

// 当单击添加属性增加一行表格项时，待填入属性值的输入框应该自动获取焦点，先在script标签间准备一个变量
// 定义一个变量 它代表标签对象 对应输入框 获取输入框对象 
const inputRef = ref(null)

// 获取store
const categoryStore  = useCategoryListStore()

// 1.定义一个根据一二三级导航获取属性列表的函数
const getAttrListData = async()=>{
  loading.value = true;
  attrList.value = await reqGetAttrListDataByCategory3Id({
    category1Id:categoryStore.category1Id,
    category2Id:categoryStore.category2Id,
    category3Id:categoryStore.category3Id,
  })
  // 请求成功后要变成false
  loading.value = false;
}

// 2.监视三级导航id
watch(()=>categoryStore.category3Id,(category3Id)=>{
  if(!category3Id){
    // 如果没传id值 则将数据内容清空 不显示属性列表
    attrList.value = [];
    return
  }
  // newValue有值的时候才需要发送请求 没有的时候不需要发送请求
  getAttrListData()
},{immediate:true}) // 表单会存储之前id 组件来回切换 因为id没变 所以监听不到 所以无法渲染，所以要立即监听


// 3.添加属性值
const addAttrValue = ()=>{
  attrInfo.attrValueList.push({
    valueName:'',
    isShowInput:true  // 是不是显示输入框 还是显示一个span标签
  })

  // 因为数据渲染是异步的 上面的数据添加后 有可能还是无法第一时间拿到值 用nextTick搭配
  nextTick(()=>{
    inputRef.value?.focus()
  })
}

// 4.失去焦点时，删除没有当前属性值的那一项(同时也可判断输入的属性值是否重复)
// 利用排它思想 若属性值重复 则删除当前
const deleteCurrentRow = (row:AttrValueModel,index:number) =>{
  // 从第0项 截取到 倒数第二项 比对所有项 看有无重复
  const item = attrInfo.attrValueList.slice(0,-1).find(item=>item.valueName===row.valueName)
  // 判断当前输入框有无值，若无值或者属性值重复 则删除当前
  if(!row.valueName || item){
    // 没有/属性值重复 则删除当前行
    attrInfo.attrValueList.splice(index,1)
    return
  }
  // 有值 就显示span标签
  row.isShowInput = false
}

// 5.修改属性值
const editAttrValue = (row:AttrValueModel,index:number)=>{
  // 让输入框显示出来 才能修改
  row.isShowInput = true
  // 获取焦点
  nextTick(()=>{
    inputRef.value?.select()   // select 不仅获取焦点 还全选文本了
  })
}

// 6.删除某一个属性值
const deleteAttrValue = (index:number)=>{
  attrInfo.attrValueList.splice(index,1)
}

// 7.添加或更新属性时的函数
const toAddOrUpdateAttr = async()=>{
  attrInfo.categoryId = categoryStore.category3Id as number
  await reqAddOrUpdateAttrInfo(attrInfo)
  ElMessage.success("属性添加成功")

  // 跳转到列表页
  isShowAttrList.value = true
  // 重新获取页面数据
  getAttrListData()
}

// 8.添加新属性时清空旧值
const toSaveAttrValue = ()=>{
  // 显示添加属性页面
  isShowAttrList.value = false

  // 清空旧值
  attrInfo.attrName = ''
  attrInfo.attrValueList = []
  // 添加属性与更新属性用的是同一个接口 如果不删掉id 则再次添加属性 会被认为是更新属性
  delete attrInfo.id
}

// 9.删除属性
const deleteAttrInfo = async(id:number)=>{
  await reqDeleteOneAttr(id)

  ElMessage.success("删除属性成功")
  // 重新发送请求 渲染剩下的数据
  // getAttrListData()

  // 也可以不发送请求 只需要将被删除了的数据从当前对象的数据中过滤掉即可
  attrList.value = attrList.value.filter(item => {
    return item.id != id;
  });
}

// 10.更新属性
const editAttr = (row:AttrInfoModel)=>{
  // 实现界面切换
  isShowAttrList.value = false
  // 覆盖原来收集的数据
  Object.assign(attrInfo,row)
}

</script>

<style>

</style>